<template>
  <div class="dept-attendance-container">
    <!-- 新增下拉框选择月份 -->
    <div class="select-month">
      <label>当前月份：</label>
      <el-select v-model="selectedMonth" placeholder="选择月份" @change="fetchDataByMonth">
        <el-option
          v-for="month in availableMonths"
          :key="month"
          :label="month"
          :value="month"
        >
        </el-option>
      </el-select>
    </div>
    <!-- 显示部门名称 -->
    <h1 class="dept-name">{{ deptName }}</h1>
    <!-- 核心指标卡片 -->
    <div class="overview-cards">
      <div class="card" v-for="(value, key, index) in overviewData" :key="key" :class="'card-bg-' + index">
        <h3>{{ getCardTitle(key) }}</h3>
        <p v-if="key === 'leaveInfo'">
          今日请假人数: {{ value.todayLeaveCount }}<br>
          待审批人数: {{ value.pendingApprovalCount }}
        </p>
        <p v-else>{{ key === 'onTimeRate' ? `${value}%` : value }}</p>
        <div v-if="key === 'noAttendanceCount'" class="card-button">
          <el-button type="primary" size="small" @click="showNoAttendanceModal = true">查看</el-button>
        </div>
      </div>
    </div>

    <!-- 趋势图表 -->
    <div class="trend-charts">
      <div id="dailyChart" class="chart"></div>
      <div id="statusChart" class="chart"></div>
    </div>

    <!-- 员工排名表格（本月迟到次数TOP5） -->
    <div class="ranking-section">
      <h2>部门员工本月考勤排名（迟到次数TOP5）</h2>
      <table class="employee-table">
        <thead>
        <tr>
          <th>员工姓名</th>
          <th>迟到次数</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(item, index) in employeeRanking" :key="index">
          <td>{{ item.nickName }}</td>
          <td>{{ item.lateCount }}</td>
        </tr>
        </tbody>
      </table>
    </div>

    <!-- 若依模态框（纯文本展示） -->
    <el-dialog
      title="今日未考勤人员名单"
      :visible.sync="showNoAttendanceModal"
      width="30%"
      center
    >
      <div v-if="!noAttendanceUsers.length" style="padding: 20px; text-align: center;">
        暂无未考勤人员
      </div>
      <div v-else style="padding: 10px 50px; text-align: left;">
        <div v-for="user in noAttendanceUsers" :key="user.userId" style="display: inline-block; text-align: left; margin: 10px; padding: 10px; background: #f8f9fa; border-radius: 8px; font-size: 20px">
          <span style="font-weight: 500; margin-right: 10px;">工号：</span>{{ user.userName }}<br>
          <span style="font-weight: 500; margin-right: 10px;">姓名：</span>{{ user.nickName }}
        </div>
      </div>
      <template #footer>
        <el-button @click="showNoAttendanceModal = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import {getSignStatistic} from "@/api/attendance/signRecord";
import {listUser} from "@/api/system/user";
import {listLeaveRecord} from "@/api/leave/leaveTeacherRecord";

export default {
  data() {
    return {
      loading: true,
      deptName: '',
      queryParams: {
        pageNum: 1,
        pageSize: 100000,
        deptId: undefined
      },
      total: '',
      userList: [],
      dateRange: [],
      overviewData: {
        deptUser: 0,
        onTimeRate: 0,
        abnormalTotal: 0,
        noAttendanceCount: 0,
        leaveInfo: {
          todayLeaveCount: 0,
          pendingApprovalCount: 0
        }
      },
      dailyAttendance: [],
      statusDistribution: [],
      employeeRanking: [],
      noAttendanceUsers: [],
      showNoAttendanceModal: false,
      leaveRecordList: [],
      availableMonths: [],
      selectedMonth: '',
    };
  },
  mounted() {
    this.fetchAllData();
  },
  methods: {
    async fetchAllData() {
      try {
        this.loading = true;
        const response = await getSignStatistic(this.queryParams);
        const deptData = response.data || [];

        if (deptData.length > 0) {
          this.deptName = deptData[0].deptName;
          this.queryParams.deptId = deptData[0].deptId;
        }

        const userResponse = await listUser(this.queryParams);
        this.userList = userResponse.rows;
        this.total = userResponse.total;

        const leaveResponse = await listLeaveRecord(this.queryParams);
        this.leaveRecordList = leaveResponse.rows;

        this.extractAvailableMonths(deptData);
        this.selectedMonth = this.getCurrentMonth();

        this.fetchDataByMonth();
      } catch (error) {
        console.error('数据加载失败', error);
        this.$message.error('加载部门考勤数据失败');
      }
    },

    extractAvailableMonths(deptData) {
      const months = new Set();
      deptData.forEach(item => {
        const date = new Date(item.signTime);
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        months.add(`${year}-${month}`);
      });
      this.availableMonths = Array.from(months).sort();
    },

    getCurrentMonth() {
      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0');
      return `${year}-${month}`;
    },

    async fetchDataByMonth() {
      const [year, month] = this.selectedMonth.split('-');
      const startDate = new Date(year, month - 1, 1);
      const endDate = new Date(year, month, 0);

      const response = await getSignStatistic(this.queryParams);
      const deptData = response.data || [];

      const monthlyDeptData = deptData.filter(item => {
        const signDate = new Date(item.signTime.split(' ')[0]);
        return signDate >= startDate && signDate <= endDate;
      });

      const today = new Date();
      const todayDeptData = monthlyDeptData.filter(item => {
        const signDate = new Date(item.signTime.split(' ')[0]);
        return signDate.getFullYear() === today.getFullYear() &&
          signDate.getMonth() === today.getMonth() &&
          signDate.getDate() === today.getDate();
      });

      this.calculateOverview(monthlyDeptData, todayDeptData);
      this.processDailyAttendance(monthlyDeptData);
      this.calculateStatusDistribution(monthlyDeptData);
      this.generateEmployeeRanking(monthlyDeptData);
      this.findNoAttendanceUsers(todayDeptData);
      this.calculateLeaveInfo();

      this.initCharts();
      this.loading = false;
    },

    calculateOverview(monthlyDeptData, todayDeptData) {
      const totalSign = monthlyDeptData.length;
      const onTimeSign = monthlyDeptData.filter(item => [0, 1].includes(item.signStatus)).length;

      const attendedUserIds = new Set(todayDeptData.map(item => item.userId));
      const noAttendanceCount = this.userList.filter(user => !attendedUserIds.has(user.userId)).length;

      this.overviewData = {
        deptUser: this.total,
        onTimeRate: (totalSign > 0 ? (onTimeSign / totalSign * 100).toFixed(1) : 0),
        abnormalTotal: monthlyDeptData.filter(item => [2, 3, 4].includes(item.signStatus)).length,
        noAttendanceCount: noAttendanceCount,
        leaveInfo: {
          todayLeaveCount: 0,
          pendingApprovalCount: 0
        }
      };
    },

    processDailyAttendance(deptData) {
      const [year, month] = this.selectedMonth.split('-');
      const startOfMonth = new Date(year, month - 1, 1);
      const endOfMonth = new Date(year, month, 0);

      const dateMap = {};
      deptData.forEach(item => {
        const date = item.signTime.split(' ')[0];
        if (!dateMap[date]) dateMap[date] = new Set();
        dateMap[date].add(item.userId);
      });

      const allDates = [];
      let current = new Date(startOfMonth);
      while (current <= endOfMonth) {
        const dateStr = `${current.getFullYear()}-${String(current.getMonth() + 1).padStart(2, '0')}-${String(current.getDate()).padStart(2, '0')}`;
        allDates.push(dateStr);
        current.setDate(current.getDate() + 1);
      }

      this.dailyAttendance = allDates.map(date => ({
        date,
        count: dateMap[date] ? dateMap[date].size : 0
      }));
    },

    calculateStatusDistribution(deptData) {
      const statusCount = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0};
      deptData.forEach(item => statusCount[item.signStatus]++);
      this.statusDistribution = Object.entries(statusCount).map(([status, count]) => ({
        name: this.getStatusText(status),
        value: count
      }));
    },

    generateEmployeeRanking(deptData) {
      const employeeStats = {};
      deptData.forEach(item => {
        const {userId, nickName, signStatus} = item;
        if (!employeeStats[userId]) {
          employeeStats[userId] = {userId, nickName, lateCount: 0, totalSign: 0};
        }
        employeeStats[userId].totalSign++;
        if ([2].includes(signStatus)) employeeStats[userId].lateCount++;
      });

      this.employeeRanking = Object.values(employeeStats)
        .sort((a, b) => b.lateCount - a.lateCount)
        .slice(0, 5);
    },

    findNoAttendanceUsers(deptData) {
      const attendedUserIds = new Set(deptData.map(item => item.userId));
      this.noAttendanceUsers = this.userList.filter(user => !attendedUserIds.has(user.userId));
    },

    initCharts() {
      // 每日出勤人数折线图
      const dailyChart = echarts.init(document.getElementById('dailyChart'));
      dailyChart.setOption({
        title: {text: '部门本月每日出勤人数'},
        tooltip: {
          trigger: 'axis',
          axisPointer: {type: 'shadow'},
          formatter: (params) => {
            const item = params[0];
            return `<div style="padding: 12px; background: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1)">
                      <div style="font-size: 14px; font-weight: 500; color: #303133;">${item.name}</div>
                      <div style="display: flex; align-items: center; gap: 6px; margin-top: 8px;">
                        <div style="width: 10px; height: 10px; background: ${item.color}; border-radius: 2px;"></div>
                        <span style="color: #606266;">出勤人数: ${item.value} 人</span>
                      </div>
                    </div>`;
          }
        },
        xAxis: {
          data: this.dailyAttendance.map(item => item.date),
          type: 'category',
          axisTick: {alignWithLabel: true},
          axisLine: {color: '#e4e7ed'},
          axisLabel: {
            color: '#606266',
            fontSize: 12,
            margin: 8
          }
        },
        yAxis: {
          type: 'value',
          splitLine: {
            lineStyle: {type: 'dashed', color: '#f0f2f5'}
          },
          axisLine: {color: '#e4e7ed'},
          axisLabel: {
            color: '#606266',
            fontSize: 12
          }
        },
        series: [{
          type: 'line',
          data: this.dailyAttendance.map(item => item.count),
          symbol: 'circle',
          symbolSize: 8,
          lineStyle: {
            color: '#409eff'
          },
          itemStyle: {
            color: '#409eff'
          }
        }]
      });

      // 状态分布饼图
      const statusChart = echarts.init(document.getElementById('statusChart'));
      statusChart.setOption({
        title: {text: '部门本月考勤状态分布'},
        tooltip: {
          trigger: 'item',
          formatter: (params) => {
            return `<div style="padding: 12px; background: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1)">
                      <div style="font-size: 14px; font-weight: 500; color: #303133;">${params.name}</div>
                      <div style="display: flex; align-items: center; gap: 6px; margin-top: 8px;">
                        <div style="width: 10px; height: 10px; background: ${params.color}; border-radius: 2px;"></div>
                        <span style="color: #606266;">次数: ${params.value}</span>
                        <span style="color: #606266; margin-left: 10px;">占比: ${params.percent.toFixed(1)}%</span>
                      </div>
                    </div>`;
          }
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          top: 'middle', // 垂直居中
          data: this.statusDistribution.map(item => item.name)
        },
        series: [{
          type: 'pie',
          data: this.statusDistribution,
          label: {formatter: '{b}: {d}%'},
          radius: ['40%', '70%'],
          center: ['50%', '50%'],
          itemStyle: {
            borderRadius: 8,
            borderWidth: 2,
            borderColor: '#fff',
            shadowBlur: 10,
            shadowColor: 'rgba(0, 0, 0, 0.1)'
          }
        }]
      });
    },

    getStatusText(status) {
      return {
        '0': '准时签到',
        '1': '准时签退',
        '2': '迟到',
        '3': '早退',
        '4': '考勤异常'
      }[status] || '未知';
    },

    getCardTitle(key) {
      return {
        deptUser: '部门总人数',
        onTimeRate: '部门本月准时率',
        abnormalTotal: '部门本月异常考勤总数(迟到+早退+考勤异常)',
        noAttendanceCount: '今日未考勤人数',
        leaveInfo: '今日请假及待审批情况'
      }[key];
    },

    calculateLeaveInfo() {
      const [year, month] = this.selectedMonth.split('-');
      const today = new Date(year, month - 1, new Date().getDate());
      const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
      let todayLeaveCount = 0;
      let pendingApprovalCount = 0;
      this.leaveRecordList.forEach(item => {
        if (item.startTime <= todayStr && item.endTime >= todayStr) {
          todayLeaveCount++;
        }
        if (item.approvalStatus === 0) {
          pendingApprovalCount++;
        }
      });
      this.overviewData.leaveInfo = {
        todayLeaveCount,
        pendingApprovalCount
      };
    }
  }
};
</script>

<style scoped>
.dept-attendance-container {
  padding: 24px 24px;
  background-color: #fff;
  border-radius: 16px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
}

.select-month {
  margin-bottom: 20px;
}

.overview-cards {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 32px;
  margin-bottom: 40px;
}

.card {
  padding: 24px;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  text-align: center;
  position: relative;
}

.card-bg-0 {
  background-color: #e5f6ff; /* 浅蓝色 */
}

.card-bg-1 {
  background-color: #fff6cc; /* 浅黄色 */
}

.card-bg-2 {
  background-color: #ffe5e5; /* 浅红色 */
}

.card-bg-3 {
  background-color: #e5ffe5; /* 浅绿色 */
}

.card-bg-4 {
  background-color: #f5e6ff; /* 浅紫色 */
}

.card-button {
  position: absolute;
  bottom: 10px;
  right: 10px;
}

.card-button button {
  background-color: #409eff;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
}

.card-button button:hover {
  background-color: #3a8ee6;
}

.trend-charts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  margin-bottom: 40px;
}

.ranking-section {
  margin-top: 40px;
}

.chart {
  height: 400px;
  border-radius: 16px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
  background-color: #fff;
}

h2 {
  font-size: 18px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 24px;
}

.dept-name {
  font-size: 24px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 24px;
  text-align: center;
}

.employee-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 24px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border-radius: 12px;
  overflow: hidden;
}

.employee-table th,
.employee-table td {
  padding: 16px 24px;
  text-align: left;
}

.employee-table th {
  background-color: #f8f9fa;
  font-weight: 600;
  color: #2c3e50;
  border-bottom: 2px solid #e4e7ed;
}

.employee-table td {
  border-bottom: 1px solid #f0f2f5;
  color: #606266;
}

.employee-table tr:hover {
  background-color: #f8f9fa;
}

.el-dialog {
  max-width: 400px;
}

.el-dialog__body {
  padding: 20px;
  text-align: center;
}

.el-dialog__body div {
  text-align: left;
}

.el-dialog__body span {
  display: inline-block;
  min-width: 60px;
  font-weight: 500;
  color: #606266;
}
</style>
